---
title: Optimizing performance
version: 1
---

import { AutoSnippet } from "/src/components/CodeSnippet";
import select from "./select/select";
import selectAsync from "./select/select_async";

With everything we've seen so far, we can already build a fully functional
application. However, you may have questions regarding performance.

In this page, we will cover a few tips and tricks to possibly optimize your code.

:::caution
Before doing any optimization, make sure to benchmark your application.
The added complexity of the optimizations may not be worth minor gains.
:::

## Filtering widget/provider rebuild using "select".

You may have noticed that, by default, using `ref.watch` causes
consumers/providers to rebuild whenever _any_ of the properties of an
object changes.  
For instance, watching a `User` and only using its "name" will still cause
the consumer to rebuild if the "age" changes.

But in case you have a consumer using only a subset of the properties,
you want to avoid rebuilding the widget when the other properties change.

This can be achieved by using the `select` functionality of providers.  
When doing so, `ref.watch` will no-longer return the full object,
but rather the selected properties.  
And your consumers/providers will now rebuild only if those selected
properties change.

<AutoSnippet {...select} />

:::info
It is possible to call `select` as many times as you wish.
You are free to call it once per property you desire.
:::

:::caution
The selected properties are expected to be immutable.
Returning a `List` and then mutating that list will not trigger a rebuild.
:::

:::caution
Using `select` slightly slows down individual read operations and
increase a tiny bit the complexity of your code.  
It may not be worth using it if those "other properties"
rarely change.
:::

### Selecting asynchronous properties

In case you are trying to optimize a provider listening to another provider,
chances are that other provider is asynchronous.

Normally, you would `ref.watch(anotherProvider.future)` to get the value.  
The issue is, `select` will apply on an `AsyncValue` – which is not something
you can await.

For this purpose, you can instead use `selectAsync`. It is unique to asynchronous
code, and enables performing a `select` operation on the data emitted by a provider.  
Its usage is similar to that of `select`, but returns a `Future` instead:

<AutoSnippet {...selectAsync} />
